// Decorator装饰器 1、是一个表达式 2、返回值是一个函数  3、函数的入参分别为target name descriptor

interface IUSer {
  userName: string;
  password: string;
  phone: number;
  login: () => void;
}

// 类装饰器
function TestClass1(target: any, discriptor: any) {
  console.log("类装饰器1");
  new target(); //执行类的实例化
  console.log("类装饰器1");
}
function TestClass2(target: any, discriptor: any) {
    console.log("类装饰器2");
    new target(); //执行类的实例化
    console.log("类装饰器2");
  }

// 类装饰器工厂
function TestClassFactory1(value: string) {
    console.log('类装饰器工厂的表达式1'+ value);
  return function (target:any,descript:any) {
    console.log("类装饰器工厂1",value);
    new target(); //执行类的实例化
    console.log("类装饰器工厂1",value);
  };
}
function TestClassFactory2(value: string) {
    return function (target:any,descript:any) {
      console.log("类装饰器工厂2",value);
      new target(); //执行类的实例化
      console.log("类装饰器工厂2",value);
    };
}

function TestClassFactory3(value:any){
    return function(target:any,discriptor:any){
        return class extends target{
            userName=value
            // login(){
            //     console.log('装饰器里的login方法');
            // }
        }
    }
}

// @TestClass
// 装饰器的执行顺序是：从上往下执行带括号的代码，然后再从下往上执行装饰器（不带括号的
// @TestClassFactory1("你好呀！ 小郑")
// @TestClass1
// @TestClass2
// @TestClassFactory2("我很好呀！ 小郑")
@TestClassFactory3("大郑")
class User implements IUSer {
  userName;
  password;
  phone;
  constructor(userName: string, password: string, phone: number) {
    console.log("执行");
    this.userName = userName;
    this.password = password;
    this.phone = phone;
  }
  login() {
    console.log(this);
    
    console.log("我成功登录了",this.userName);
  }
}

var user = new User('小郑','123456',10086)
user.login()
